import logging
import os.path
import random
import time
from collections import OrderedDict

import pandas as pd
import pydirectinput as pdg
import pyautogui as pag
import cv2

IMAGE_PATH = "images"


class NageController:
    default_skill_keys = ["f1", "f2", "f3"]

    # default_active_skill_keys = ["f4"]

    def __init__(self, skill_keys=None, active_skill_keys=None):
        self.skill_keys = skill_keys if skill_keys is not None else self.default_skill_keys
        # self.active_skill_keys = active_skill_keys if active_skill_keys is not None else self.default_active_skill_keys

    def countdown(self, drange=(15, 60)):
        time.sleep(3)
        duration = random.randint(*drange)
        for i in reversed(list(range(duration))):
            logging.info(f"倒计时：{i}")
            time.sleep(1)

    def change_skills(self):
        """改变技能"""
        key_idx = 0
        key_count = len(self.skill_keys)
        while True:
            pdg.press(self.skill_keys[key_idx])
            self.countdown()
            if key_idx < key_count - 1:
                key_idx += 1
            else:
                key_idx = 0

    def simulate_human(self):
        pass


def get_item_pos(image_path):
    target_pos = pag.locateOnScreen(image_path)
    goto_pos = pag.center(target_pos)
    return goto_pos


def get_and_click(image):
    x, y = get_item_pos(image)
    pdg.moveTo(x, y, duration=1)
    time.sleep(2)
    # pydirectinput.click()
    # pdg.click()
    pdg.mouseDown()
    time.sleep(0.1)
    pdg.mouseUp()
    # time.sleep(5)


def sell():
    time.sleep(2)
    pdg.moveTo(100, 100, duration=3)
    pdg.click()
    image = "images/sell.png"
    get_and_click(image)


def check_blank():
    pass


def get_blank_coor(X, Y, width, border):
    return (X - border, Y - border, width + 2 * border, width + 2 * border)


def compare_blank_similarity(coor, blank_image_path):
    X_center = coor[0] + int(coor[2] / 2)
    Y_center = coor[1] + int(coor[3] / 2)
    pdg.moveTo(X_center, Y_center, duration=2)
    screenshot = pag.screenshot(region=coor)
    image1 = os.path.join(IMAGE_PATH, "screenshot_frame.png")
    screenshot.save(image1)
    image2 = blank_image_path
    image1 = cv2.imread(image1)
    image2 = cv2.imread(image2)
    hist_img1 = cv2.calcHist([image1], [0, 1, 2], None, [256, 256, 256], [0, 256, 0, 256, 0, 256])
    hist_img1[255, 255, 255] = 0  # ignore all white pixels
    cv2.normalize(hist_img1, hist_img1, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX)
    hist_img2 = cv2.calcHist([image2], [0, 1, 2], None, [256, 256, 256], [0, 256, 0, 256, 0, 256])
    hist_img2[255, 255, 255] = 0  # ignore all white pixels
    cv2.normalize(hist_img2, hist_img2, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX)
    # Find the metric value
    metric_val = cv2.compareHist(hist_img1, hist_img2, cv2.HISTCMP_CORREL)
    return metric_val


def screenshot_coor(coor, image_path=None, point_and_save=False, expand=0):
    X1, Y1, X2, Y2 = coor
    if point_and_save:
        X_center = int((X1 + X2) / 2)
        Y_center = int((Y1 + Y2) / 2)
        pdg.moveTo(X_center, Y_center, duration=2)
    X1 -= expand
    Y2 -= expand
    width = X2 - X1 + expand
    height = Y2 - Y1 + expand
    screenshot = pag.screenshot(region=(X1, Y1, width, height))
    if image_path is None:
        image_path = os.path.join(IMAGE_PATH, "screenshot_frame.png")
    screenshot.save(image_path)
    return image_path


def compare_similarity(target_image_path, reference_image_path):
    # print("target_image_path:", target_image_path)
    # print("reference_image_path:", reference_image_path)
    image1 = cv2.imread(target_image_path)
    image2 = cv2.imread(reference_image_path)
    hist_img1 = cv2.calcHist([image1], [0, 1, 2], None, [256, 256, 256], [0, 256, 0, 256, 0, 256])
    hist_img1[255, 255, 255] = 0  # ignore all white pixels
    cv2.normalize(hist_img1, hist_img1, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX)
    hist_img2 = cv2.calcHist([image2], [0, 1, 2], None, [256, 256, 256], [0, 256, 0, 256, 0, 256])
    hist_img2[255, 255, 255] = 0  # ignore all white pixels
    cv2.normalize(hist_img2, hist_img2, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX)
    # Find the metric value
    metric_val = cv2.compareHist(hist_img1, hist_img2, cv2.HISTCMP_CORREL)
    return metric_val


def compare_item():
    pass


def scan_blank_similarity(frames, target_image_path=None, blank_image_path=None):
    similarity_list = []
    for idx in frames.index:
        row = frames.loc[idx]
        coor = (int(row["X"]), int(row["Y"]), int(row["X1"]), int(row["Y1"]))
        # coor = get_blank_coor(int(row["X"]), int(row["Y"]), width, border)
        image_path = screenshot_coor(coor, image_path=target_image_path, point_and_save=True, expand=3)
        similarity = compare_similarity(image_path, blank_image_path)
        # similarity = compare_blank_similarity(coor, blank_image_path=blank_image_path)
        print(f"行{row['row']},列{row['col']}相似度：{similarity}")
        similarity_list.append({
            "idx": idx,
            "similarity": similarity,
            "X-center": int(row["X-center"]),
            "Y-center": int(row["Y-center"])
        })
    return similarity_list


def store_sell_frame():
    pdg.moveTo(300, 300, duration=3)
    pdg.click()
    frames = pd.read_excel("data/item_frames.xlsx",
                           sheet_name="store_frame",
                           converters={
                               "X-center": int,
                               "Y-center": int
                           })
    print(frames.head())
    not_blank_list = []
    blank_image_path = os.path.join(IMAGE_PATH, "blank_store_frame.png")
    target_image_path = os.path.join(IMAGE_PATH, "blank_sell_store_image.png")
    similarity_list = scan_blank_similarity(frames, target_image_path=target_image_path,
                                            blank_image_path=blank_image_path)
    for result in similarity_list:
        if result["similarity"] <= 0.95:
            not_blank_list.append(result)

    confirm_image = "images/confirm.png"
    first_box = frames.loc[0]
    X, Y = int(first_box["X-center"]), int(first_box["Y-center"])
    for i in range(len(not_blank_list)):
        pdg.moveTo(X, Y, duration=2)
        time.sleep(2)
        pdg.click()
        pdg.rightClick()
        time.sleep(2)
        try:
            confirm_pos = get_item_pos(confirm_image)
            pdg.moveTo(*confirm_pos)
            time.sleep(1)
            click()
        except Exception as e:
            logging.info(e)


def get_box_info():
    box_frames = OrderedDict()
    frames = pd.read_excel("data/item_frames.xlsx",
                           sheet_name="box_frame",
                           converters={
                               "X-center": int,
                               "Y-center": int
                           })
    for idx in frames.index:
        row = frames.loc[idx]
        box_frames[idx] = {
            "X-center": row["X-center"],
            "Y-center": row["Y-center"],
            "blank": True
        }
    return box_frames


def package_frame():
    pdg.moveTo(300, 300, duration=3)
    pdg.click()
    border = 3
    width = 31
    frames = pd.read_excel("data/item_frames.xlsx",
                           sheet_name="package_frame",
                           converters={
                               "X-center": int,
                               "Y-center": int
                           })
    print(frames.head())
    not_blank_list = []
    blank_image_path = os.path.join(IMAGE_PATH, "blank_package_frame.png")
    similarity_list = scan_blank_similarity(frames, width, border, blank_image_path=blank_image_path)
    # for result in similarity_list:
    #     if result["similarity"] <= 0.95:
    #         not_blank_list.append(result)

    # break
    # 箱子信息
    box_frames = get_box_info()
    for result in similarity_list:
        if result["similarity"] < 0.9:
            pdg.moveTo(result["X-center"], result["Y-center"], duration=1)
            print("暂停")
            time.sleep(2)
            click()
            for box_id, box_param in box_frames.items():
                print(f"{box_id}:", box_param)
                if box_param["blank"]:
                    pdg.moveTo(box_param["X-center"], box_param["Y-center"], duration=1)
                    click()
                    break
            break


# screenshot = pag.screenshot(region=(X1 - border, Y1 - border, width + 2 * border, width + 2 * border))
# screenshot.save("./images/blank_store.png")
# pos = get_item_pos(image)
# print(pos)
# pdg.moveTo(*pos)
# data = pd.read_excel("data/item_frames.xlsx", sheet_name="frame")


def click():
    pdg.mouseDown()
    pdg.mouseUp()


def double_click():
    pdg.mouseDown()
    pdg.mouseUp()
    pdg.mouseDown()
    pdg.mouseUp()


def move():
    time.sleep(2)
    pdg.moveTo(634, 365, duration=1)
    time.sleep(2)
    click()

    # pdg.click()
    # print("暂停")
    # time.sleep(2)
    # pdg.click()


def enter_game():
    # import win32con
    # import win32api
    time.sleep(2)
    pdg.moveTo(473, 606, duration=1)
    pdg.click()
    time.sleep(2)
    double_click()
    # pdg.doubleClick(464, 723)
    # pdg.mouseDown()
    # time.sleep(0.1)
    # pdg.mouseUp()
    # win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTDOWN, 100, 100)
    # time.sleep(0.2)
    # win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTUP, 100, 100)

    # get_and_click("images/enter_game.png")


def fight():
    pdg.moveTo(641, 555)
    pdg.click()

    fist_path = os.path.join(IMAGE_PATH, "fight_fist")
    fist1 = os.path.join(fist_path, "fist2.png")
    ordinary_hand = os.path.join(IMAGE_PATH, "ordinary_hand", "ordinary_hand1.png")

    width = 38
    scan_height = 100
    scan_width = 50
    scan_Y0 = 180
    # scan_X0_center = int(0 + width/2)
    # scan_Y0_center= int(555 + width/2)
    screen_width = 1280
    screen_height = 960
    # people
    found = False
    while scan_Y0 <= 555:
        scan_X0 = 0
        Y_1 = scan_Y0 + width
        while scan_X0 <= screen_width:
            pdg.moveTo(scan_X0, scan_Y0)
            # X_center, Y_center = pdg.position()
            # X_0 = int(scan_X0_center - width / 2)
            X_1 = scan_X0 + width
            coor = (scan_X0, scan_Y0, X_1, Y_1)
            scan_image_path = screenshot_coor(coor,
                                              image_path=os.path.join(IMAGE_PATH, "temp_images", "fight_fist_scan.png"))
            sim_to_fist = compare_similarity(scan_image_path, fist1)
            sim_to_ord = compare_similarity(scan_image_path, ordinary_hand)
            print("sim_to_fist:", sim_to_fist)
            print("sim_to_ord:", sim_to_ord)
            if sim_to_fist > sim_to_ord:
                X_center = int((scan_X0 + X_1) / 2)
                Y_center = int((scan_Y0 + Y_1) / 2)
                pdg.moveTo(X_center, Y_center)
                click()
                found = True
                break
            scan_X0 += scan_width
        if found:
            break
        scan_Y0 += scan_height
        # time.sleep(3)


# class
# left_top_vertex = (235, 280)

if __name__ == "__main__":
    # store_sell_frame()
    # package_frame()
    # fight()
    # move()
    # sell()
    # enter_game()

    pdg.moveTo(50, 50)
    pdg.click()
    time.sleep(2)
    pdg.press("left", presses=3)
    # time.sleep(2)
    # for i in range(3):
    #     image_path = f"images/temp_images/full_scene_{i}.png"
    #     screenshot = pag.screenshot(region=(0, 0, 1280, 960))
    #     screenshot.save(image_path)
    #     x, y = scan_road(image_path)
    #     pdg.moveTo(x, y, duration=2)
    #     click()
    #     time.sleep(5)
